/*
 * @Date         : 2024-05-12 17:44:11 星期0
 * @Author       : xut
 * @Description  :
 */
import grpc from "@grpc/grpc-js"

export const echoServiceImpl = {
  unaryEcho: (call, cb) => {
    // request header 接收
    const incomingTimestamps = call.metadata.get("timestamp")

    if (incomingTimestamps.length > 0) {
      console.log("Timestamp from metadata:")
      for (const [index, value] of incomingTimestamps.entries()) {
        console.log(` ${index}. ${value}`)
      }
    }

    // response header 响应
    const responseHeaderMetadata = new grpc.Metadata()
    responseHeaderMetadata.set("timestamp", new Date().toISOString())
    call.sendMetadata(responseHeaderMetadata)

    // response trailers 响应
    const responseTrailerMetadata = new grpc.Metadata()
    responseTrailerMetadata.set("timestamp", new Date().toISOString())

    const response = { value: "Hello " + call.request.name }
    cb(null, response, responseTrailerMetadata)
  },

  serverStreamingEcho: (call) => {
    // request header 接收
    const incomingTimestamps = call.metadata.get("timestamp")

    if (incomingTimestamps.length > 0) {
      console.log("Timestamp from metadata:")
      for (const [index, value] of incomingTimestamps.entries()) {
        console.log(` ${index}. ${value}`)
      }
    }

    // response header 响应
    const responseHeaderMetadata = new grpc.Metadata()
    responseHeaderMetadata.set("timestamp", new Date().toISOString())
    call.sendMetadata(responseHeaderMetadata)

    const hello = "Hello From Server"

    for (let i = 0; i < hello.length; i++) {
      call.write({ value: hello[i] })
    }

    // response trailers 响应
    const responseTrailerMetadata = new grpc.Metadata()
    responseTrailerMetadata.set("timestamp", new Date().toISOString())
    call.end(responseTrailerMetadata)
  },

  clientStreamingEcho: (call, cb) => {
    // request header 接收
    const incomingTimestamps = call.metadata.get("timestamp")

    if (incomingTimestamps.length > 0) {
      console.log("Timestamp from metadata:")
      for (const [index, value] of incomingTimestamps.entries()) {
        console.log(` ${index}. ${value}`)
      }
    }

    // response header 响应
    const responseHeaderMetadata = new grpc.Metadata()
    responseHeaderMetadata.set("timestamp", new Date().toISOString())
    call.sendMetadata(responseHeaderMetadata)

    let result = ""
    call.on("data", (data) => {
      result += data.name
    })

    // 此处监听无效，status 事件似乎只对客户端有效？
    call.on("status", (status) => {
      console.log("🚀 ~ call.on ~ status:", status)
    })

    call.on("end", () => {
      // response trailers 响应
      const responseTrailerMetadata = new grpc.Metadata()
      responseTrailerMetadata.set("timestamp", new Date().toISOString())

      console.log("Client Streaming end ", result)
      cb(null, { value: `Server Received: ${result}` }, responseTrailerMetadata)
    })
  },

  bidirectionalStreamingEcho: (call) => {
    // request header 接收
    const incomingTimestamps = call.metadata.get("timestamp")

    if (incomingTimestamps.length > 0) {
      console.log("Timestamp from metadata:")
      for (const [index, value] of incomingTimestamps.entries()) {
        console.log(` ${index}. ${value}`)
      }
    }

    // response header 响应
    const responseHeaderMetadata = new grpc.Metadata()
    responseHeaderMetadata.set("timestamp", new Date().toISOString())
    call.sendMetadata(responseHeaderMetadata)

    let result = ""

    call.on("data", (data) => {
      const char = data.name
      result += char

      call.write({ value: char.charCodeAt(0) })
    })

    // status 事件只有客户可用
    // call.on("status", (status) => {
    //   if (grpcStatus[status.code] === grpcStatus.OK) {
    //     cb({ message: `Received: ${result}` })
    //   }
    // })

    call.on("end", () => {
      // response trailers 响应
      const responseTrailerMetadata = new grpc.Metadata()
      responseTrailerMetadata.set("timestamp", new Date().toISOString())
      console.log("Duplex Streaming end, Received: ", result)
      call.end(responseTrailerMetadata)
    })
  },
}
